<template>
  <div class="bar-charts-com">
    <div class="chart" ref="chart">

    </div>
  </div>
</template>
<script>
import * as echarts from 'echarts'
import {getRandomColor, hexToHexWithAlpha} from "@/utils/constant";

/**
 * @description 柱状图组件
 * source 数据源 {xData:[],yData:{aaa:[],bbb:[]},yLabel:''} yData 若需要多条柱子则在对象中传入多组Data，对象的Key为系列名 yLabel为Y轴上的名称
 * stack 是否堆叠值
 * legend 是否显示图例
 * grid 布局
 * barRadius 柱子圆角 分别为 左上 右上 右下 左下
 * barAlpha 柱子透明度 0-100
 * barGradient 柱子是否渐变 为true时barAlpha失效
 * barWidth 柱子宽度 不传值为auto
 * barGap 柱子间隔 百分比 不传值为auto
 * alignWithLabel x坐标轴刻度线和标签是否对齐
 */
export default {
  name: 'BarCharts',
  props: {
    source: {
      type: Object,
      required: true,
    },
    loading: {
      type: Boolean,
      default: true
    },
    legend: {
      type: Boolean,
      default: false
    },
    grid: {
      type: Object,
      default: () => {
        return {top: 40, bottom: 30, left: 20, right: 10}
      }
    },
    barRadius: {
      type: Array,
      default: () => {
        return [30, 30, 0, 0]
      }
    },
    barAlpha: {
      type: Number,
      default: 100
    },
    barGradient: {
      type: Boolean,
      default: false
    },
    barWidth:{
      type:Number,
      default:0
    },
    barGap:{
      type:Number,
      default:null
    },
    stack:{
      type:Boolean,
      default:false
    }
  },
  watch: {
    source: {
      deep: true,
      immediate: true,
      handler(val) {
        this.$nextTick(() => {
          if (val) {
            if ((Array.isArray(val) && val.length) || Object.keys(val).length) {
              const option = this.getOption();
              this.getChart()
              this.chart.setOption(option)
            }
          }
        })
      }
    },
    loading: {
      immediate: true,
      handler(val) {
        this.$nextTick(() => {
          this.getChart()
          if (val) {
            this.chart.showLoading({
              text: '加载中',
              textColor: '#fff',
              maskColor: 'rgba(0,0,0,0)'
            })
          } else {
            this.chart.hideLoading()
          }
        })
      }
    }
  },
  data() {
    return {
      chart: null
    }
  },
  methods: {
    getChart() {
      this.chart = this.chart || echarts.init(this.$refs.chart)
    },
    getOption() {
      const keys = Object.keys(this.source.yData)
      const color = getRandomColor(keys.length)
      const series = keys.map((item, index) => {
        const value = this.source.yData[item]
        let result = {name: item, type: 'bar', data: value}
        const currentColor = color[index]
        const colorOption = this.barGradient ? new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {offset: 0, color: currentColor},
          {offset: 1, color: hexToHexWithAlpha(currentColor, 30)},
        ]) : hexToHexWithAlpha(currentColor, this.barAlpha)
        result.itemStyle = {
          color: colorOption,
          borderRadius:this.barRadius
        }
        result.stack=this.stack;
        if(this.barWidth){
          result.barWidth=this.barWidth
        }
        if(this.barGap!==null){
          result.barGap=this.barGap+'%';
        }
        return result
      })
      let option = {
        color,
        grid: {...this.grid, containLabel: true},
        xAxis: {
          type: 'category',
          data: this.source.xData,
          axisLabel: {
            color: '#A3A3C9',
            rotate: 30,
            fontSize: 10,
            formatter: (value) => {
              let ret = '';
              let maxLength = 4;
              let valLength = value.length;
              let rowN = Math.ceil(valLength / maxLength);
              if (rowN > 1) {
                for (let i = 0; i < rowN; i++) {
                  let temp = '';
                  const start = i * maxLength;
                  const end = start + maxLength;
                  temp = value.substring(start, end) + '\n';
                  ret += temp;
                }
                return ret;
              } else {
                return value;
              }
            }
          },
          axisLine: {lineStyle: {color: '#0B3771'}},
          axisTick: {show: false},
        },
        yAxis: {
          type: 'value',
          name: this.source.yLabel || '',
          nameTextStyle: {color: '#A3A3C9'},
          axisLabel: {color: '#A3A3C9'},
          splitLine: {lineStyle: {color: 'rgba(199,199,200,0.1)', width: 1, type: 'solid'}}
        },
        series: series,
        tooltip: {
          trigger: 'axis'
        }
      }
      if (this.legend) {
        option.legend = {data: Object.keys(this.source.yData), textStyle: {color: '#fff'}}
      }
      return option
    }
  },
  beforeDestroy() {
    this.chart && this.chart.dispose();
    this.chart = null
  }
}
</script>
<style lang="scss" scoped>
.bar-charts-com {
  width: 100%;
  height: 100%;

  .chart {
    width: 100%;
    height: 100%;
  }
}
</style>
